package org.winexpress

import grails.converters.JSON
import org.codehaus.groovy.grails.web.json.JSONObject
import org.codehaus.groovy.grails.web.json.JSONArray

import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;


class CustomerController {
    // shared methods
    def sendResponse(statusCode) {
        if (statusCode == 404) {
            JSONObject o = new JSONObject()
            o.put(statusCode, true)
            render o as JSON
        }
        
        response.status = statusCode
        render response
        
        // 200-OK (e.g. GET success)
        // 201-Created (e.g. POST success)
        // 304-Not Modified (e.g. already authenticated)
        // 403-Forbidden (e.g. LOGIN failure)
        // 400-Bad Request (e.g. PUT,POST,DELETE failure)
        // 404-Not Found (e.g. GET failure)
        // 406-Not Acceptable (e.g. username not unique)
        // 500-Internal Server Error (other...)
    }
    
    // takes in Customer c, subject s
    def sendHtmlMailToCustomer(c, p, s) {
        def activationURL = 'http://localhost:8080/WineXpress/customer/' + c.id + '/activate'
//        forward(action:"show",id:4, params:[name: c.firstName, activateLink: activationURL,  now: new Date()])
        forward(controller:"awsSes", action:"sendHtmlMailFromTemplate", params:[email: c.email, subject: s, firstName: c.firstName, un: c.username, pw: p, activationURL: activationURL])
    }
    
    def createShoppingCart(customerId) {
        
        println "HERE IN WEB SERVICE :: createShoppingCart"

        // get form values
//        def custId = params['customerId']
        def custId = customerId
        
        // create a JSONObject to send to winexpress server
        JSONObject o = new JSONObject()
        o.put("customerId",custId)
        
        // to create use POST
        HttpClient httpclient = new DefaultHttpClient()
        HttpResponse response
        // consume winexpress server web service
        HttpPost httppost = new HttpPost("http://localhost:8080/WineXpress/customer/" + custId + "/cart/") // WineXpress Server's URI
        StringEntity se = new StringEntity(o.toString())          
        httppost.setEntity(se);          
        response = httpclient.execute(httppost);
        
        // get response code
        StatusLine status = response.getStatusLine()
        int statusCode = status.getStatusCode()
        
        println statusCode
        if (statusCode == 201) {
            println 201 + " shopcart OK"
        }
        if (statusCode == 400) {
            println 400 + " shopcart FAILED"
        }
        
        return statusCode
  
    }
    
//    def getCustomerIDByUsername(username) {
//       
//        // consume winexpress server web service
//        def txt = new URL("http://localhost:8080/WineXpress/customer/" + username).text
//        
//        if (txt.getAt(0) == '{') {
//            JSONObject o = new JSONObject(txt)
//            if (o.has("404")) {
//                if (o.get("404") == true) {
//                    println = 'No such customer.<br/><br/>'
//                }
//            }
//            else {
//                return o.get("customerId")
//            }
//        }
//        else {
//            flash.message = 'No such customer.<br/><br/>'
//            redirect(uri:"/")
//        }
//    }
    
    
    
    // REST operations
    // GET
    def show = {
//        println 'CustomerController >> Show >> START'
        
        CustomerManagement cman = new CustomerManagement()
        
        if (params.id) {
            if (params.id.isInteger() == true) {
                if (Customer.exists(params.id)) {
                    def c = cman.getCustomerByID(params.id)
                    if (c.activationStatus == true) {
                        render c as JSON
                        sendResponse(200)
                        println 'Show customer by ID >> ' + c.id + " " + c
                    }
                    else {
                        sendResponse(404)
                    }
                }
                else {
                    sendResponse(404)
                }
            }      
            else {
                def c = cman.getCustomerByUsername(params.id)
                if (c == null) {
                    sendResponse(404)
                } 
                else {
                    if (c.activationStatus == true) {
                        render c as JSON
                        sendResponse(200)
                        
                        println 'Show customer by username >> ' + params.id + " " + c.username
                    }
                    else {
                        sendResponse(404)
                    }
                }
            }
        }
        else {
            def allC = cman.listCustomers()
            if (allC.length() > 0) {
                render allC as JSON
                sendResponse(200)
            }
            else {
                sendResponse(404)
            }
            
            println 'Listing all customers >> ' + allC
        }
        
//        println 'CustomerController >> Show >> END'
    }
    
    def activateCustomer = {
        def customerId = params['id']
        
        CustomerManagement cman = new CustomerManagement()
        def c = cman.getCustomerByID(customerId)
        if (c.activationStatus == false) {
            println "in activate"

            c.activationStatus = true
            
            def result = cman.updateActivationStatus(c)
            if (result == true) {
    //            println 'CustomerController >> Update >> ' + result
    println 'create shop cart now'
                // create shopping cart when activated
//                forward(controller:"webService", action:"createShoppingCart", params:[customerId: c.id])
createShoppingCart(c.id)
                sendResponse(200)
                redirect(url:"http://localhost:8088/WineXpressClient/memberLogin")
            }
            else {
    //            println 'CustomerController >> Update >> ' + result
                sendResponse(400)
            }    
        }
        else {
            println "304"
            sendResponse(304)
            redirect(url:"http://localhost:8088/WineXpressClient/memberLogin")  
        }
    }
    
    
    
    // PUT
    def update = {

//        if (params.id && Customer.exists(params.id) && params.postalCode && params.password) {
//            def c = cman.getCustomerByID(params.id)
       
        
//        println 'CustomerController >> update >> START'
        
        JSONObject o = request.JSON
//        
        CustomerManagement cman = new CustomerManagement()
        CountryManagement ctyman = new CountryManagement()
        PasswordManagement pwman = new PasswordManagement()
        
        def c = cman.getCustomerByID(o.get("id"))
        if (o.has("password")) { 
            if (o.get("password") != "") {
                def generatedPassword = pwman.generatePassword() // email this
                c.password = pwman.encodePassword(generatedPassword) // store this 
                println c.password 
            }
        }
        if (o.has("email")) { if (o.get("email") != "") c.email = o.get("email"); println c.email }
        if (o.has("blkHouseNo")) { c.blkHouseNo = o.get("blkHouseNo"); println c.blkHouseNo }
        if (o.has("streetName")) { c.streetName = o.get("streetName"); println c.streetName }
        if (o.has("unitNo")) { c.unitNo = o.get("unitNo"); println c.unitNo }
        if (o.has("postalCode")) { c.postalCode = o.get("postalCode"); println c.postalCode }
        if (o.has("telNo")) { c.telNo = o.get("telNo"); println c.telNo  }
        def cty = ctyman.getCountryForDbByCountryName(o.get("country"))
        if (cty != null) {
    //        c.countryId = cty.id
            c.country = cty
        }
        
        def result = cman.updateCustomer(c)
        if (result == true) {
//            println 'CustomerController >> Update >> ' + result
            sendResponse(200)
        }
        else {
//            println 'CustomerController >> Update >> ' + result
            sendResponse(400)
        }       
    }
    
    
    
    // DELETE
    def delete = {
        println 'CustomerController >> delete >> START'
        
        println 'CustomerController >> delete >> END'
    }
    
    // POST
    def save = {
//        println 'CustomerController >> save >> START'
        
        JSONObject o = request.JSON
        println o
        
        CustomerManagement cman = new CustomerManagement()
        CountryManagement ctyman = new CountryManagement()
        PasswordManagement pwman = new PasswordManagement()
        ShoppingCartManagement scman = new ShoppingCartManagement()
        
        Customer c = new Customer()
        c.username = o.get("username")
        def generatedPassword = pwman.generatePassword() // email this
        c.password = pwman.encodePassword(generatedPassword) // store this

        c.activationStatus = false
        // my null for lastlogin does not work!
        Date d = new Date();
        c.lastLogin = d
        println c.lastLogin

        if (o.has("lastName")) { if (o.get("lastName") != "") c.lastName = o.get("lastName") else c.lastName = "-"; println c.lastName }
        if (o.has("firstName")) { if (o.get("firstName") != "") c.firstName = o.get("firstName") else c.firstName = "-"; println c.firstName }
        if (o.has("birthdate")) { if (o.get("birthdate") != "") c.birthdate = o.get("birthdate") else c.birthdate = null; println c.birthdate }
//        c.lastName = o.get("lastName")
//        c.firstName = o.get("firstName")
//        c.birthdate = o.get("birthdate")

        c.email = o.get("email")
        println c.email
        if (o.has("blkHouseNo")) { if (o.get("blkHouseNo") != "") c.blkHouseNo = o.get("blkHouseNo") else c.blkHouseNo = "-"; println c.blkHouseNo }
        if (o.has("streetName")) { if (o.get("streetName") != "") c.streetName = o.get("streetName") else c.streetName = "-"; println c.streetName }
        if (o.has("unitNo")) { if (o.get("unitNo") != "") c.unitNo = o.get("unitNo") else c.unitNo = "-"; println c.unitNo }
        if (o.has("postalCode")) { if (o.get("postalCode") != "") c.postalCode = o.get("postalCode") else c.postalCode = "-"; println c.postalCode }
        
        if (o.has("country")) {
            def cty = ctyman.getCountryForDbByCountryName(o.get("country"))
            if (cty != null) {
        //        c.countryId = cty.id
                c.country = cty
            }
        }
        else {
            c.country = null
            println c.country
        }
        println c.country
        
        if (o.has("telNo")) { if (o.get("telNo") != "") c.telNo = o.get("telNo") else c.telNo = "-"; println c.telNo }
        
        if (isUniqueUsername(c) == true) {
        
            def result = cman.addCustomer(c)
            if (result == true) {
        //            println 'CustomerController >> Update >> ' + result
                // send email
                sendHtmlMailToCustomer(c, generatedPassword, "WineXpress.com: Registration Successful")
                sendResponse(201)
            }
            else {
        //            println 'CustomerController >> Update >> ' + result
                sendResponse(400)
            }
        }
        else {
            sendResponse(406)
        }

//        println 'CustomerController >> save >> END'
    }
    
    // supporting operations
    def isUniqueUsername(cust) {
        
        def status = false
        
        CustomerManagement cman = new CustomerManagement()
        Customer c = null
        
        c = cman.getCustomerByUsername(cust.username)
        
        if (c == null) {
            status = true 
        }
        
        return status
    }
    
}
